﻿using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.EMMA;
using HandyControl.Tools.Extension;
using LYR_RPA.dialog;
using LYR_RPA.models.entity;
using LYR_RPA.models.enums;
using LYR_RPA.models.project;
using LYR_RPA.Properties;
using LYR_RPA.service;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Documents;
namespace LYR_RPA.utils
{
    public static class CommonUtils
    {

        public static ObservableCollection<Project> ProjectCollections { get; set; } = new ObservableCollection<Project>();//项目展示的集合
        public static ObservableCollection<Execute> ExecuteCollections { get; set; } = new ObservableCollection<Execute>();//项目执行集合
        public static ObservableCollection<Execute> LogCollections { get; set; } = new ObservableCollection<Execute>();//日志集合
        public static ObservableCollection<Project> RemoveProjects { get; set; } = new ObservableCollection<Project>();//移除的项目集合
        public static ObservableCollection<Project> RemoveFolders { get; set; } = new ObservableCollection<Project>();//移除的目录集合
        public static string RobotPath = Settings.Default.RobotPath;
        private static readonly WebSocketClient WebSocketClient;
        private static int index = 0;
        public static bool IsExecute { get; set; }

        static CommonUtils()
        {
            WebSocketClient = WebSocketClient.Instance;
        }

        /*
         * 读取项目列表
         */
        public static ObservableCollection<Project> ReadProject()
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                ProjectCollections.Clear();
                try
                {
                    List<Folder> test = SQLiteApply.SelectFolder();
                }
                catch (Exception ex)
                {
                    // 打印或记录异常信息
                    Console.WriteLine($"查询异常: {ex.Message}");
                    Console.WriteLine($"堆栈跟踪: {ex.StackTrace}");
                }
                //数据库查找目录
                List<Folder> FolderLsit = SQLiteApply.SelectFolder();
                
                //查询被移除的项目
                List<Project> ProjectList = SQLiteApply.SelectRemoveProject();
                /*string commonPath = AppDomain.CurrentDomain.BaseDirectory + "\\common";
                if (Directory.Exists(commonPath))
                {
                    string[] directories = Directory.GetDirectories(commonPath);
                    foreach (string directorie in directories)
                    {
                        string[] items = Directory.GetDirectories(directorie);
                        foreach (string item in items)
                        {

                            if (!string.IsNullOrEmpty(VerifyProject(item)))
                            {

                                Project project = new Project
                                {
                                    Path = item,
                                    Module = Path.GetFileName(directorie),
                                    ScriptName = Path.GetFileName(item),
                                    UpdateTime = Directory.GetLastWriteTime(item).ToString("yyyy-MM-dd")
                                };
                                ProjectCollections.Add(project);
                            }

                        }
                    }
                }*/
                if (FolderLsit.Count == 0)
                {
                    //取出本地文档
                    string defaultPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "\\UiPath";
                    if (Directory.Exists(defaultPath))
                    {
                        string[] directories = Directory.GetDirectories(defaultPath);

                        foreach (string directorie in directories)
                        {
                            string modelName= Path.GetFileName(directorie);
                            if (!string.IsNullOrEmpty(VerifyProject(directorie)))
                            {
                                Project project = new Project
                                {
                                    Path = directorie,
                                    ScriptName = Path.GetFileName(directorie),
                                    UpdateTime = Directory.GetLastWriteTime(directorie).ToString("yyyy-MM-dd")
                                };
                                ProjectCollections.Add(project);
                            }
                            else
                            {
                                string[] projects = Directory.GetDirectories(directorie);
                                foreach (string item in projects)
                                {
                                    if (!string.IsNullOrEmpty(VerifyProject(item)))
                                    {
                                        Project project = new Project
                                        {
                                            Path = item,
                                            Module = modelName,
                                            ScriptName = Path.GetFileName(item),
                                            UpdateTime = Directory.GetLastWriteTime(item).ToString("yyyy-MM-dd")
                                        };
                                        ProjectCollections.Add(project);
                                    }
                                        
                                }
                            }
                        }
                    }

                }
                //查询数据库的数据
                foreach (Folder f in FolderLsit)
                {
                    int isFolder = f.IsFolder;
                    //判断是目录还是项目
                    if (isFolder == 1)
                    {
                        string[] folders = Directory.GetDirectories(f.path);
                        foreach (string folder in folders)
                        {
                            string modelName = Path.GetFileName(folder);
                            if (string.IsNullOrEmpty(VerifyProject(folder)))
                            {
                                //文件夹下的的文件夹下的项目
                                string[] projects = Directory.GetDirectories(folder);
                                foreach (string item in projects)
                                {
                                    if (!string.IsNullOrEmpty(VerifyProject(item)))
                                    {
                                        Project project = new Project
                                        {
                                            Path = item,
                                            Module = modelName,
                                            ScriptName = Path.GetFileName(item),
                                            UpdateTime = Directory.GetLastWriteTime(item).ToString("yyyy-MM-dd")
                                        };
                                        ProjectCollections.Add(project);
                                    }
                                }
                            }
                            else
                            {
                                ProjectCollections.Add(new Project()
                                {
                                    Path = folder,
                                    ScriptName = Path.GetFileName(folder),
                                    UpdateTime = Directory.GetLastWriteTime(folder).ToString("yyyy-MM-dd")
                                });
                            }
                        }
                    }
                    else
                    {
                        //判断项目是否正常
                        if (!string.IsNullOrEmpty(VerifyProject(f.path.ToString())))
                        {
                            ProjectCollections.Add(new Project()
                            {
                                Path = f.path.ToString(),
                                ScriptName = Path.GetFileName(f.path.ToString()),
                                UpdateTime = Directory.GetLastWriteTime(f.path.ToString()).ToString("yyyy-MM-dd")
                            });
                        }
                    }
                }
                //过滤移除的项目
                foreach (Project project in ProjectList)
                {
                    for (int i = 0; i < ProjectCollections.Count; i++)
                    {
                        if (project.Path.ToString().Equals(ProjectCollections[i].Path))
                        {
                            ProjectCollections.RemoveAt(i);
                            break;
                        }
                    }

                }
            });

            return ProjectCollections;
        } 
        /*
         * 搜索项目关键词
         */
        public static ObservableCollection<Project> SearchProject(string content)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                List<Project> SearchList = new List<Project>();
                foreach(Project project in ProjectCollections)
                {
                    if (project.ScriptName.Contains(content))
                    {
                        SearchList.Add(project);
                    }
                }
                ProjectCollections.Clear();
                foreach (Project project in SearchList)
                {
                    ProjectCollections.Add(project);
                }
            });

            return ProjectCollections;
        }

        /*
         * 执行任务
         */
        public static async void AddExecuteTask(Execute execute)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                if (execute != null && File.Exists(RobotPath))
                {
                    ExecuteCollections.Add(execute);
                }
                else
                {
                    if (!File.Exists(RobotPath))
                    {
                        new DialogBox().ShowMessage("环境异常", "没有可执行程序！", "确定");
                    }
                }

            });

            if (IsExecute)
            {
                return;
            }
            IsExecute = true;
            index = 0;
            while (index < ExecuteCollections.Count)
            {
                var executeTask = ExecuteCollections[index];
                //判断是否执行
                if (!executeTask.IsExecute && !executeTask.IsTask)
                {

                    executeTask.IsExecute = true;

                    var project = new Project() { Path = executeTask.Path, ScriptName = executeTask.Name, UpdateTime = executeTask.CreateTime ,RpaId=executeTask.RpaId};
                    

                    //校验项目是否是uipath项目
                    string path = VerifyProject(executeTask.Path);
                    //判断该项目是否可以执行
                    if (string.IsNullOrEmpty(path))
                    {
                        if (executeTask.IsCommand)
                        {
                            _ = WebSocketClient.SendMessage(JSONUtils.ObjectToString(Result<Project>.ResultContent(ResultEnum.EXECUTE_FAIL, project)));
                        }

                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            executeTask.Msg = "未找到执行入口";
                            executeTask.State = "Red";
                        });
                    }
                    else
                    {
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            executeTask.Msg = executeTask.IsAwait? executeTask.Msg: "正在执行" ;
                            executeTask.State = "#0078D4";
                        });
                        
                        
                        //开始执行
                        bool code = await ExecuteProcess(executeTask, path, project);
                        
                        

                        //使用UI线程
                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            if (code)
                            {
                                executeTask.State = "Green";
                                executeTask.Msg = "执行完毕！";
                            }
                            else
                            {
                                //因为取消执行也算异常，判断是否是取消还是执行中的异常
                                if (executeTask.IsCancel)
                                {
                                    executeTask.State = "Orange";
                                    executeTask.Msg = "取消执行！";
                                }
                                else
                                {
                                    executeTask.State = "Red";
                                    executeTask.Msg = "执行异常！";
                                }

                            }
                            if (executeTask.IsExecute)
                            {
                                LogCollections.Insert(0, executeTask);
                            }

                            ExecuteCollections.Remove(executeTask);
                            index--;
                        });
                        SQLiteApply.InsertLog(executeTask);
                    }
                }
                index++;
            }
            IsExecute = false;
        }

        /*
         * 启动程序执行
         */
        private static async Task<bool> ExecuteProcess(Execute execute, string path,Project project)
        {
            //判断是否是远程调用
            if (execute.IsCommand)
            {
                _ = WebSocketClient.SendMessage(JSONUtils.ObjectToString(Result<Project>.ResultContent(ResultEnum.EXECUTE, project)));
            }
            //设置程序启动信息
            ProcessStartInfo processStartInfo = new ProcessStartInfo
            {
                FileName = RobotPath,
                Arguments = $"-file \"{path}\" ",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                CreateNoWindow = true
            };
            execute.Processing = new Process
            {
                StartInfo = processStartInfo,
                EnableRaisingEvents = true
            };
            execute.Processing.ErrorDataReceived += (sender, e) =>
            {
                if (!String.IsNullOrEmpty(e.Data))
                {
                    //execute.Errers.Add(e.Data);
                    // 使用正则表达式提取包含关键字的行
                    if (execute.Errers.Count<=2)
                    {
                        execute.Errers.Add(e.Data);
                    }
                }

            };

            execute.Processing.OutputDataReceived += (sender, e) =>
            {
                if (!String.IsNullOrEmpty(e.Data))
                {
                    //处理输出信息
                    execute.Errers.Add(e.Data);
                }
            };
            //判断是否是任务
            if (execute.IsAwait)
            {
                //如果小于当前日期直接执行
                if (execute.ExecuteTime <= DateTime.Now)
                {
                    execute.Processing.Start();
                }
                else
                {
                    //大于当前日期则等待到执行日期时执行
                    TimeSpan time = execute.ExecuteTime - DateTime.Now;//计算当前日期和执行日期相差的秒数
                    Console.WriteLine((int)time.TotalSeconds);
                    //等待秒数
                    await Task.Delay((int)(time.TotalSeconds)*1000);
                    //执行
                    execute.Processing.Start();
                }
            }
            else
            {
                execute.Processing.Start();
            }
            
            
            //开始执行
            execute.CreateTime = execute.Processing.StartTime.ToString("yyyy-MM-dd HH:mm:ss");
            //开始处理进程状态
            execute.Processing.BeginErrorReadLine();
            execute.Processing.BeginOutputReadLine();
            //string error = execute.Processing.StandardError.ReadToEnd();
            //等待执行退出
            execute.Processing.WaitForExit();
            //判断执行状态码是否正常
            int count = execute.Processing.ExitCode;
            execute.Processing.Close();
            if (execute.IsCommand)
            {
                if (count == 0)
                {
                    
                    _=WebSocketClient.SendMessage(JSONUtils.ObjectToString(Result<Project>.ResultContent(ResultEnum.EXECUTE_SUCCESS, project)));
                }
                else
                {
                    _ = WebSocketClient.SendMessage(JSONUtils.ObjectToString(Result<Project>.ResultContent(ResultEnum.EXECUTE_FAIL, execute.ErrersString, project)));
                }
                    
            }
            Console.WriteLine(execute.ErrersString);
            return count == 0;

        }

        /*
         * 校验项目内是一个还是多个
         */
        public static string VerifyProject(string path)
        {
            if (!Directory.Exists(path))
            {
                return "";
            }
            //取出项目中的文件夹
            string[] files = Directory.GetFiles(path);
            int count = 0;
            string subPath = "";
            foreach (string file in files)
            {
                //判断是否是文件
                if (File.Exists(file))
                {
                    //判断文件是否是.xaml后缀
                    if (file.EndsWith(".xaml"))
                    {
                        count++;
                        subPath = file;
                    }
                }
            }
            //如果只有一个xaml的话直接返回
            if (count == 1)
            {
                return subPath;
            }
            else if (count > 1)
            {
                //判断project.json是否存在
                if (File.Exists(path + "\\project.json"))
                {
                    //读取文件
                    string content = File.ReadAllText(path + "\\project.json");
                    //序列化文件内容
                    var startMain = JSONUtils.StringToObject<StartMain>(content);
                    subPath = path + $"\\{startMain.main}";
                    //判断读取的主入口是否存在
                    if (File.Exists(subPath))
                    {
                        return subPath;
                    }

                }
                else
                {
                    //如果没有project.json且存在多个.xaml则考虑检查是否有Main
                }
            }
            //返回未找到入口
            return "";
        }

        /*
         * 读取日志数据
         */
        public static ObservableCollection<Execute> ReadLog()
        {
            LogCollections.Clear();
            List<Execute> executes= SQLiteApply.ReadLogs();
            foreach (Execute execute in executes)
            {
                LogCollections.Insert(0, execute);
            }
            return LogCollections;
        }
        /*
         * 读取日志数据
         */
        public static bool ClearLogs()
        {
            
            return SQLiteApply.ClearLogs();
        }
        /*
         * 读取日志数据
         */
        public static ObservableCollection<Execute> SearchLog(string content)
        {
            

            Application.Current.Dispatcher.Invoke(() =>
            {
                List<Execute> SearchList = new List<Execute>();
                foreach (Execute execute in LogCollections)
                {
                    if (execute.Name.Contains(content))
                    {
                        SearchList.Add(execute);
                    }
                }
                LogCollections.Clear();
                foreach (Execute execute in SearchList)
                {
                    LogCollections.Add(execute);
                }
            });
            return LogCollections;
        }

        /*
         * 
         * 关闭进程方法
         */
        public static void CloseProcess(string processName)
        {

            Process[] processes = Process.GetProcessesByName(processName);

            if (processes.Length > 0)
            {
                foreach (var process in processes)
                {
                    try
                    {
                        // 杀死进程
                        process.Kill();
                        Console.WriteLine($"成功杀死进程: {process.ProcessName} (ID: {process.Id})");
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"无法杀死进程: {process.ProcessName} (ID: {process.Id}). 错误信息: {ex.Message}");
                    }
                }
            }
            else
            {
                Console.WriteLine($"没有找到名称为 {processName} 的进程");
            }
        }

        /*
         * 读取移除项目的集合
         */
        public static ObservableCollection<Project> ReadRemoveProject()
        {
            RemoveProjects.Clear();
            List<Project> projects = SQLiteApply.SelectRemoveProject();
            foreach (Project project in projects)
            {
                string path = project.Path;
                RemoveProjects.Add(new Project()
                {
                    Path = path,
                    ScriptName = Path.GetFileName(path),
                    UpdateTime = Directory.GetLastWriteTime(path).ToString("yyyy-MM-dd")
                });
            }
            return RemoveProjects;
        }

        /*
        * 读取移除目录的集合
        */
        public static ObservableCollection<Project> ReadRemoveFolder()
        {
            RemoveFolders.Clear();
            List<Folder> folders = SQLiteApply.SelectFolder();
            foreach (Folder folder in folders)
            {
                string path = folder.Path;
                RemoveFolders.Add(new Project()
                {
                    Path = path,
                    ScriptName = Path.GetFileName(path),
                    UpdateTime = Directory.GetLastWriteTime(path).ToString("yyyy-MM-dd")
                });
            }
            return RemoveFolders;
        }


    }
}
